package pers.mihao.quickstream.publish.strategy.directory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import pers.mihao.quickstream.account.model.vo.Account;
import pers.mihao.quickstream.account.service.AccountService;
import pers.mihao.quickstream.common.util.CollectionUtil;
import pers.mihao.quickstream.publish.strategy.context.ChooseContext;
import pers.mihao.quickstream.publish.strategy.directory.filter.AccountDirectoryFilter;
import pers.mihao.quickstream.publish.strategy.dto.ChooseAccount;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author mihao
 * @since 2024/11/24
 */
@Component("accountDirectory")
public class AccountDirectoryFace implements AccountDirectory {

    @Resource
    AccountService accountService;

    @Autowired
    List<AccountDirectoryFilter> filterList;

    @Override
    public List<ChooseAccount> list(ChooseContext chooseContext) {
        List<Account> accounts = queryAllAccount(chooseContext.getOpUserId());
        AccountDirectoryFilter filter = buildFilterChain(chooseContext);
        accounts = filter.filter(accounts);
        return accounts.stream().map(a -> ChooseAccount.builder()
                        .accountId(a.getAccountId())
                        .platformCode(a.getPlatform().getCode()).build())
                .collect(Collectors.toList());
    }

    private AccountDirectoryFilter buildFilterChain(ChooseContext chooseContext) {

        List<AccountDirectoryFilter> filterChain = filterList.stream().filter(f -> f.match(chooseContext))
                .sorted(Comparator.comparingInt(AccountDirectoryFilter::sort))
                .collect(Collectors.toList());

        if (CollectionUtil.isEmpty(filterChain)) {
            return accounts -> new ArrayList<>();
        }

        AccountDirectoryFilterChain pre = new AccountDirectoryFilterChain(), _pre = pre;
        for (AccountDirectoryFilter filter : filterChain) {
            AccountDirectoryFilterChain chain = new AccountDirectoryFilterChain();
            chain.curr = filter;
            pre.next = chain;
            pre = chain;
        }
        return _pre.next;
    }

    private static class AccountDirectoryFilterChain implements AccountDirectoryFilter {
        AccountDirectoryFilter next;
        AccountDirectoryFilter curr;

        @Override
        public List<Account> filter(List<Account> accounts) {
            if (next == null) {
                return curr.filter(accounts);
            } else {
                return next.filter(curr.filter(accounts));
            }
        }
    }

    private List<Account> queryAllAccount(Long userId) {
        return accountService.listAllAccountByUserId(userId);
    }
}
